package cn.iocoder.yudao.module.search.tenant;

import cn.hutool.core.collection.CollUtil;
import lombok.experimental.UtilityClass;

import java.util.*;

/**
 * 星球过滤器
 * 在同一租户内部通过planet_id字段实现星球级别的数据过滤
 * 
 * @author 芋道源码
 */
@UtilityClass
public class PlanetFilter {

    /**
     * 星球ID字段名
     */
    public static final String PLANET_ID_FIELD = "planet_id";

    /**
     * 为文档添加星球ID字段
     * 
     * @param document 原始文档
     * @param planetId 星球ID
     * @return 添加了星球ID的文档
     */
    public static Map<String, Object> addPlanetId(Map<String, Object> document, Long planetId) {
        if (document == null) {
            document = new HashMap<>();
        }
        if (planetId != null) {
            document.put(PLANET_ID_FIELD, planetId);
        }
        return document;
    }



    /**
     * 构建星球过滤条件
     * 
     * @param planetId 星球ID
     * @return 星球过滤条件
     */
    public static Map<String, Object> buildPlanetFilter(Long planetId) {
        if (planetId == null) {
            return Collections.emptyMap();
        }
        
        Map<String, Object> filter = new HashMap<>();
        filter.put("term", Map.of(PLANET_ID_FIELD, planetId));
        return filter;
    }

    /**
     * 构建多个星球的过滤条件
     * 
     * @param planetIds 星球ID列表
     * @return 星球过滤条件
     */
    public static Map<String, Object> buildPlanetFilter(Collection<Long> planetIds) {
        if (CollUtil.isEmpty(planetIds)) {
            return Collections.emptyMap();
        }
        
        if (planetIds.size() == 1) {
            return buildPlanetFilter(planetIds.iterator().next());
        }
        
        Map<String, Object> filter = new HashMap<>();
        filter.put("terms", Map.of(PLANET_ID_FIELD, planetIds));
        return filter;
    }



    /**
     * 为过滤条件添加星球过滤
     *
     * @param filters 原始过滤条件
     * @param planetId 星球ID
     * @return 添加星球过滤后的条件
     */
    public static Map<String, Object> addPlanetFilter(Map<String, Object> filters, Long planetId) {
        if (planetId == null) {
            return filters;
        }

        if (filters == null) {
            filters = new HashMap<>();
        }

        // 添加星球ID过滤条件
        filters.put(PLANET_ID_FIELD, planetId);
        return filters;
    }

    /**
     * 将星球过滤条件添加到查询中
     *
     * @param query 原始查询
     * @param planetFilter 星球过滤条件
     * @return 添加了星球过滤的查询
     */
    public static Map<String, Object> addPlanetFilterToQuery(Map<String, Object> query, Map<String, Object> planetFilter) {
        if (query == null) {
            query = new HashMap<>();
        }
        
        if (CollUtil.isEmpty(planetFilter)) {
            return query;
        }
        
        // 如果查询中已经有bool查询，则添加到must中
        if (query.containsKey("bool")) {
            @SuppressWarnings("unchecked")
            Map<String, Object> boolQuery = (Map<String, Object>) query.get("bool");
            
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> mustList = (List<Map<String, Object>>) boolQuery.computeIfAbsent("must", k -> new ArrayList<>());
            mustList.add(planetFilter);
        } else {
            // 如果没有bool查询，则创建一个新的bool查询
            Map<String, Object> boolQuery = new HashMap<>();
            List<Map<String, Object>> mustList = new ArrayList<>();
            
            // 如果原查询不为空，将其作为must条件之一
            if (!query.isEmpty()) {
                mustList.add(new HashMap<>(query));
                query.clear();
            }
            
            // 添加星球过滤条件
            mustList.add(planetFilter);
            
            boolQuery.put("must", mustList);
            query.put("bool", boolQuery);
        }
        
        return query;
    }



    /**
     * 检查文档是否属于指定星球
     * 
     * @param document 文档
     * @param planetId 星球ID
     * @return 是否属于指定星球
     */
    public static boolean belongsToPlanet(Map<String, Object> document, Long planetId) {
        if (document == null || planetId == null) {
            return false;
        }
        
        Object docPlanetId = document.get(PLANET_ID_FIELD);
        if (docPlanetId == null) {
            return false;
        }
        
        // 处理不同类型的星球ID
        if (docPlanetId instanceof Number) {
            return planetId.equals(((Number) docPlanetId).longValue());
        } else if (docPlanetId instanceof String) {
            try {
                return planetId.equals(Long.parseLong((String) docPlanetId));
            } catch (NumberFormatException e) {
                return false;
            }
        }
        
        return planetId.equals(docPlanetId);
    }



    /**
     * 从文档中提取星球ID
     * 
     * @param document 文档
     * @return 星球ID
     */
    public static Long extractPlanetId(Map<String, Object> document) {
        if (document == null) {
            return null;
        }
        
        Object planetId = document.get(PLANET_ID_FIELD);
        if (planetId == null) {
            return null;
        }
        
        if (planetId instanceof Number) {
            return ((Number) planetId).longValue();
        } else if (planetId instanceof String) {
            try {
                return Long.parseLong((String) planetId);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        
        return null;
    }

}
